/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2009 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.Collections.Generic;

using Gtk;
using Glade;

using Galaxium.Core;
using Galaxium.Gui;
using Galaxium.Gui.GtkGui;

using Anculus.Core;

using Galaxium.Client;

namespace Galaxium.Protocol.Irc.GtkGui
{
	public class ServerConsoleWindow
	{
		[Widget ("ServerConsoleWindow")]
		private Window _window;
		[Widget ("ConsoleView")]
		private TextView _consoleView;
		[Widget ("InputBox")]
		private HBox _inputBox;
		[Widget ("CheckAuto")]
		private CheckButton _checkAuto;
		
		private IrcSession _session;
		private SimpleEntry _inputEntry;
		
		public IrcSession Session
		{
			get { return _session; }
		}
		
		public bool Visible
		{
			get { return(_window.Visible); }
			set
			{
				if (value == _window.Visible)
					if (value)
						_window.Present();
					else	
						return;
				
				_window.Visible = value;
			}
		}
		
		public ServerConsoleWindow(IrcSession session)
		{
			_session = session;
			
			XML gxml = new XML (GladeUtility.GetGladeResourceStream (typeof (ServerConsoleWindow).Assembly, "ServerConsoleWindow.glade"), null, null);
			gxml.Autoconnect (this);
			
			GtkUtility.EnableComposite (_window);
			
			_window.Icon = IconUtility.GetIcon ("irc-console", IconSizes.Small);
			
			_window.Title = "Network: "+session.RemoteServerSettings.NetworkName;
			
			// Make sure we listen for messages received from the server.
			session.Connection.MessageReceived += MessageReceived;
			
			_window.DeleteEvent += OnServerConsoleDialogDelete;
			
			_window.ShowAll();
			_window.Visible = (session.Account as IrcAccount).ShowConsole;
			_checkAuto.Active = _window.Visible;
			_checkAuto.Toggled += CheckAutoToggled;
			
			_inputEntry = new SimpleEntry (true);
			_inputEntry.TextSubmitted += CommandSubmitted;
			_inputBox.PackStart (_inputEntry, true, true, 0);
			_inputBox.ShowAll();
			
			_inputEntry.GrabFocus ();
		}
		
		void CommandSubmitted (object obj, SimpleEntryEventArgs args)
		{
			bool isCommand = args.Text.Length > 1 && args.Text[0] == '/' && args.Text[1] != '/';
			string error = null;
			
			if (isCommand)
			{
				if (!CommandInputHandlerUtility.HandleCommand (this, Session, null, args.Text, out error))
				{
					ThreadUtility.Dispatch (new VoidDelegate (delegate
					{
						TextIter iter = _consoleView.Buffer.EndIter;
						_consoleView.Buffer.Insert (ref iter, error + "\n");
						_consoleView.ScrollToIter (_consoleView.Buffer.EndIter, 0.0, true, 0.0, 0.0);
					}));
				}
			}
		}
		
		public void CheckAutoToggled (object obj, EventArgs args)
		{
			(_session.Account as IrcAccount).ShowConsole = _checkAuto.Active;
			AccountUtility.Save (_session.Account);
		}
		
		public void MessageReceived (object obj, ServerEventArgs args)
		{
			string parameters = String.Empty;
			
			if (args.Message == null)
			{
				Log.Warn ("Received a event with no message!");
				return;
			}
			
			if (args.Message.HasParameters)
				foreach (string param in args.Message.Parameters)
					parameters += param + " ";
			
			if (args.Message.Identifier == null || args.Message.Identifier.Hostname == null)
				return;
			
			string message = String.Format ("{0}> {1}\n", DateTime.Now.ToShortTimeString(), args.Output);
			
			ThreadUtility.Dispatch (new VoidDelegate (delegate
			{
				TextIter iter = _consoleView.Buffer.EndIter;
				_consoleView.Buffer.Insert (ref iter, message);
				
				_consoleView.ScrollToIter (_consoleView.Buffer.EndIter, 0.4, true, 0.0, 1.0);
			}));
		}
		
		public void Destroy()
		{
			_window.Hide();
			_window.Destroy();
		}
		
		private void OnServerConsoleDialogDelete (object sender, DeleteEventArgs args)
		{
			args.RetVal = true;
			Visible = !Visible;
		}
	}
}
